#include <stdio.h>
#include <stdlib.h>
#include <cuda.h>
#include <math.h>
size_t LenofArray(float *p)
{
size_t length=0;
for(;*p!='\0';p++)
length++;
return length;
}
int matrix_add(float *A,float *B,float *C,int W)
{
char * p="matrix_add.ptx";
char * p_ker="matrix_add";
if (cuInit(0) != CUDA_SUCCESS) exit (0);
int deviceCount = 0;
cuDeviceGetCount(&deviceCount);
if (deviceCount == 0)
{
printf("There is no device supporting CUDA.");
exit (0);
}
CUdevice cuDevice_drv = 0;
cuDeviceGet(&cuDevice_drv, 0);
CUcontext cuContext_drv;
cuCtxCreate(&cuContext_drv, 0, cuDevice_drv);
CUmodule cuModule_drv;
cuModuleLoad(&cuModule_drv, p);
CUfunction  vecAdd;
cuModuleGetFunction(&vecAdd,cuModule_drv,p_ker);
#define ALIGN_OFFSET(offset, alignment) (offset) = ((offset) + (alignment) - 1) & ~((alignment)-1)
int offset = 0;
size_t size;
void *  ptr;
CUdeviceptr ptx_A;
size=sizeof(float)*LenofArray(A);
cuMemAlloc(&ptx_A, size);
cuMemcpyHtoD(ptx_A, A, size);
ptr = (void**)(size_t)ptx_A;
ALIGN_OFFSET(offset, __alignof(ptr));
cuParamSetv(vecAdd, offset, &ptr, sizeof(ptr));
offset += sizeof(ptr);

CUdeviceptr ptx_B;
size=sizeof(float)*LenofArray(B);
cuMemAlloc(&ptx_B, size);
cuMemcpyHtoD(ptx_B, B, size);
ptr = (void**)(size_t)ptx_B;
ALIGN_OFFSET(offset, __alignof(ptr));
cuParamSetv(vecAdd, offset, &ptr, sizeof(ptr));
offset += sizeof(ptr);

CUdeviceptr ptx_C;
size=sizeof(float)*LenofArray(C);
cuMemAlloc(&ptx_C, size);
cuMemcpyHtoD(ptx_C, C, size);
ptr = (void**)(size_t)ptx_C;
ALIGN_OFFSET(offset, __alignof(ptr));
cuParamSetv(vecAdd, offset, &ptr, sizeof(ptr));
offset += sizeof(ptr);

size=sizeof(int);
ALIGN_OFFSET(offset, __alignof(W));
cuParamSeti(vecAdd, offset, W);
offset += sizeof(W);

cuParamSetSize(vecAdd, offset);
int blocksize=16;
int gridsize=(int)sqrt(LenofArray(A))/blocksize;
cuFuncSetBlockShape(vecAdd,blocksize,blocksize,1);
cuLaunchGrid(vecAdd,gridsize,gridsize);
size=sizeof(float)*LenofArray(A);
cuMemcpyDtoH(A,ptx_A,size);
size=sizeof(float)*LenofArray(B);
cuMemcpyDtoH(B,ptx_B,size);
size=sizeof(float)*LenofArray(C);
cuMemcpyDtoH(C,ptx_C,size);
size=sizeof(int);
return 1;
}
